package cn.com.xiaoshoujia.wxpay.config;

import cn.com.xiaoshoujia.activities.exception.ActivityException;
import cn.com.xiaoshoujia.utils.XMLUtil;
import cn.com.xiaoshoujia.wxpay.utils.HttpClientUtil;
import net.sf.json.JSONObject;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.ssl.SSLContexts;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.DigestUtils;

import javax.net.ssl.SSLContext;
import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.security.KeyStore;
import java.util.*;


public class WeixinPayConfig {

    private static final Logger logger = LoggerFactory.getLogger(WeixinPayConfig.class);

    /**
     * 统一下单URL
     */
    public static String URL = "https://api.mch.weixin.qq.com/pay/unifiedorder";
    /**
     * 回调URL
     */
    /* 线上 team.topsales.cc */
    /* 测试 101.200.183.100:8085 */
    public static String notify_Url = "http://team.topsales.cc/xiaoshoujia_team_wx_web/wxpay/notify";
    /**
     * 公众账号ID
     */
    /* 测试 wx0cf433d702be9008*/
    /* 线上 wx184cc15493c9c2e8*/
    public static String APP_ID = "wx184cc15493c9c2e8";
    /**
     * 商户号
     */
    /* 测试 1299076401*/
    /* 线上 1390270302*/
    public static String mch_id = "1390270302";

    public static String mch_key = "691t299o076p401s014a670l992e141s";

    /**
     * 生成sign
     *
     * @param sortedMap
     * @param key
     * @return
     */
    public static String buildSignature(SortedMap<String, String> sortedMap, String key) {
        StringBuilder sb = new StringBuilder();
        for (Map.Entry<String, String> entry : sortedMap.entrySet()) {
            sb.append(entry.getKey() + "=" + entry.getValue()).append("&");
        }
        sb.append("key=" + key);
        String sign = DigestUtils.md5DigestAsHex(sb.toString().getBytes()).toUpperCase();
        return sign;
    }

    /**
     * 获取随机字符串
     *
     * @return
     */
    public static String getNonceStr() {
        return UUID.randomUUID().toString().replace("-", "");
    }

    /**
     * 终端IP
     *
     * @param request
     * @return
     */
    public static String getIpAddr(HttpServletRequest request) {
        InetAddress addr = null;
        try {
            addr = InetAddress.getLocalHost();
        } catch (UnknownHostException e) {
            return request.getRemoteAddr();
        }
        byte[] ipAddr = addr.getAddress();
        String ipAddrStr = "";
        for (int i = 0; i < ipAddr.length; i++) {
            if (i > 0) {
                ipAddrStr += ".";
            }
            ipAddrStr += ipAddr[i] & 0xFF;
        }
        return ipAddrStr;
    }

    /**
     * @Author: yangrui
     * @Description: 获取prepay_id
     * @Date: 上午11:18 2017/7/18
     */
    public static String getH5(String body, String total_fee, String openid, String out_trade_no, HttpServletRequest request) {
        SortedMap<String, String> sortedMap = new TreeMap<String, String>();
        sortedMap.put("appid", APP_ID);
        sortedMap.put("mch_id", mch_id);
        sortedMap.put("nonce_str", getNonceStr());
        sortedMap.put("body", body);
        sortedMap.put("out_trade_no", out_trade_no);
        sortedMap.put("total_fee", total_fee);
        sortedMap.put("spbill_create_ip", getIpAddr(request));
        sortedMap.put("notify_url", notify_Url);
        sortedMap.put("trade_type", "JSAPI");
        sortedMap.put("openid", openid);
        String sign = WeixinPayConfig.buildSignature(sortedMap, WeixinPayConfig.mch_key);
        sortedMap.put("sign", sign);

        String reqxml = XMLUtil.map2xml(sortedMap);
        String str = HttpClientUtil.httpPost(URL, reqxml);

        SortedMap<String, String> map = XMLUtil.xml2map(str);
        for (Map.Entry<String, String> entry : map.entrySet()) {
            logger.info("wx {}", entry.getKey() + "--" + entry.getValue());
        }
        String return_code = map.get("return_code");
        String result_code = map.get("result_code");
        if ("SUCCESS".equals(return_code) && "SUCCESS".equals(result_code)) {
            String prepay_id = map.get("prepay_id");
            logger.info("wx prepay_id {}", prepay_id);
            SortedMap<String, String> sortedMap1 = new TreeMap<String, String>();
            sortedMap1.put("appId", WeixinPayConfig.APP_ID);
            sortedMap1.put("timeStamp", String.valueOf((int) (Calendar.getInstance().getTimeInMillis() / 1000)));
            sortedMap1.put("nonceStr", UUID.randomUUID().toString().replace("-", ""));
            String packageStr = "prepay_id=" + prepay_id;
            sortedMap1.put("package", packageStr);
            sortedMap1.put("signType", "MD5");
            String sign1 = WeixinPayConfig.buildSignature(sortedMap1, WeixinPayConfig.mch_key);
            sortedMap1.put("paySign", sign1);
            return JSONObject.fromObject(sortedMap1).toString();
        } else {
            throw new ActivityException(map.get("return_msg"));
        }
    }

    /**
     * @Author: yangrui
     * @Description: 微信退款
     * @Date: 下午4:07 2017/8/8
     */
    public static String refund(String orderId, String totalFee) throws Exception {
        //指定读取证书格式为PKCS12
        KeyStore keyStore = KeyStore.getInstance("PKCS12");
        //读取本机存放的PKCS12证书文件
//        /home/topsales/weixin-pay
//        /home/xiaoshoujia/weixin-pay
//        /Users/yangrui/Desktop
        FileInputStream instream = new FileInputStream(new File("/home/topsales/weixin-pay/cert-2 topsales/apiclient_cert.p12"));
        try {
            //指定PKCS12的密码(商户ID)
            keyStore.load(instream, mch_id.toCharArray());
        } finally {
            instream.close();
        }
        SSLContext sslcontext = SSLContexts.custom()
                .loadKeyMaterial(keyStore, mch_id.toCharArray()).build();
        //指定TLS版本
        SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
                sslcontext, new String[]{"TLSv1"}, null,
                SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);
        //设置httpclient的SSLSocketFactory
        CloseableHttpClient httpclient = HttpClients.custom()
                .setSSLSocketFactory(sslsf)
                .build();
        HttpPost httpPost = new HttpPost("https://api.mch.weixin.qq.com/secapi/pay/refund");
        String out_refund_no = String.valueOf(System.currentTimeMillis());
        SortedMap<String, String> sortedMap = new TreeMap<String, String>();
        sortedMap.put("appid", APP_ID);
        sortedMap.put("mch_id", mch_id);
        sortedMap.put("nonce_str", getNonceStr());
        sortedMap.put("out_trade_no", orderId);
        sortedMap.put("out_refund_no", out_refund_no);
        sortedMap.put("total_fee", totalFee);
        sortedMap.put("refund_fee", totalFee);
        String sign = WeixinPayConfig.buildSignature(sortedMap, WeixinPayConfig.mch_key);
        sortedMap.put("sign", sign);
        String reqxml = XMLUtil.map2xml(sortedMap);
        StringEntity se = new StringEntity(reqxml);
        httpPost.setEntity(se);
        CloseableHttpResponse response = httpclient.execute(httpPost);
        HttpEntity entity = response.getEntity();
        if (entity != null) {
            System.out.println("Response content length: " + entity.getContentLength());
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(entity.getContent()));
            String text;
            while ((text = bufferedReader.readLine()) != null) {
                logger.info("text {}", text);
            }

        }
        return null;
    }

    /**
     * @Author: yangrui
     * @Description: 退款查询
     * @Date: 上午10:06 2017/8/10
     */
    public static String refundQuery(String orderId) {
        String testUrl = "https://api.mch.weixin.qq.com/pay/refundquery";
        SortedMap<String, String> sortedMap = new TreeMap<String, String>();
        sortedMap.put("appid", APP_ID);
        sortedMap.put("mch_id", mch_id);
        sortedMap.put("nonce_str", getNonceStr());
        sortedMap.put("out_trade_no", orderId);
        String sign = WeixinPayConfig.buildSignature(sortedMap, WeixinPayConfig.mch_key);
        sortedMap.put("sign", sign);
        String reqxml = XMLUtil.map2xml(sortedMap);
        String str = HttpClientUtil.httpPost(testUrl, reqxml);
        SortedMap<String, String> map = XMLUtil.xml2map(str);
        String refundStatus = map.get("refund_status_0");

        return refundStatus;
    }

    public static void main(String[] args) {

        System.out.println(refundQuery("1504839395562934325"));
    }

}
